# -*- encoding: utf-8 -*-
""" StreamCZ plugin module for www.stream.cz """

from lib.basePlugin import *
import re
import urllib


CDN_URL  = "http://cdn-dispatcher.stream.cz/?id=%d"
RE_DATE = re.compile('(\d{1,2}\.\d{1,2}\.\d{4})')
RE_URL  = re.compile('''url\(['"]([^'")]+)['"]\)''')
RE_CDN_ID = re.compile('cdnID=(\d+)')
RE_PAGE = re.compile('&page=(\d+)')


class StreamCZPlugin(BasePlugin):
    LOGPREFIX = "[StreamCZ plugin] "
    BASE_URL = "http://www.stream.cz"
    SEARCH_TYPE  = ['search_type_our=y&search_type_user=y',
                    'search_type_our=y',
                    'search_type_user=y']
    SEARCH_ORDER = ['relevance', 'timecreate', 'starcount']
    MAX_COUNT = [10, 20, 30, 40, 50]

    @plugin_folder
    def root(self):
        """ plugin root folder """
        self.core.setSorting('NONE')
        yield PFolder(u'<Hledat video>', call='search')

        # List base categories:
        self.wget.request(self.BASE_URL)
        for a in self.wget.select('#menu > ul > li > a'):
            yield PFolder(label=a.text, call='list_category',
                        param={'path': a['href']}
                    )

        yield PFolder(u'<Site map>', call='sitemap')


    @plugin_folder
    def list_category(self, path):
        """ list subcategories """
        self.core.setSorting('NONE')
        self.wget.request( self.BASE_URL )
        menu_a = self.wget.select_first('#menu > ul > li > a[href="%s"]' % path)
        if not menu_a:
            raise Exception("menu item not found for path: "+path)

        if menu_a.parent.ul:
            # submenu found:

            #yield ...nejnovejsi...
            #yield ...nejsledovanejsi...
            #yield ...nejoblibenejsi...

            for a in menu_a.parent.ul.select('li a'):
                if a['class'] == u'menu_achiv':
                    call = 'list_archive'
                else:
                    call = 'list'
                yield PFolder(a.text, call=call,
                        param={'path': a['href']})
        else:
            # render list:
            for item in self.list_videos(path):
                yield item


    @plugin_folder
    def list_archive(self, path):
        self.core.setSorting('NONE')
        url = self.full_url(path)
        self.wget.request( url )
        for a in self.wget.select('#catmenu ul.third li a'):
            yield PFolder(a.text, call='list',
                    param={'path': a['href']})


    @plugin_folder
    def sitemap(self):
        self.core.setSorting('NONE')
        self.wget.request( self.BASE_URL )
        for li in self.wget.select('#sitemap li'):
            a = li.select_first('a')
            label = a.text
            if li.get('class') == 'archiv':
                label += ' (Archiv)'
            if li.h6:
                label = u'* %s *' % label
            yield PFolder(label, call='list', param={'path': a['href']})


    @plugin_folder
    def list(self, path):
        """ list videos """
        for item in self.list_videos(path):
            yield item



    ### Search ###

    @plugin_folder
    def search(self):
        """ search folder """
        yield PFolder(label=u'<Nové hledání>', call='new_search')
        for qtext in self.get_saved_searches():
            del_url = self.core.generateURL(call='delete_search', qtext=qtext)
            del_action = 'XBMC.RunPlugin(%s)' % del_url
            yield PFolder(label=qtext, call='search_result',
                            param={'qtext': qtext},
                            menuItems=[('Vymazat', del_action)] )


    @plugin_call
    def new_search(self):
        """ search new text """
        qtext = self.core.textDialog('Search videos')
        if not qtext:
            raise CancelOperation()
        list_url = self.core.generateURL(call='search_result', qtext=qtext)
        self.core.execute('Container.Update(%s)' % list_url)


    @plugin_folder
    def search_result(self, qtext, page=0):
        """ Search items on web and display result in as plugin folder """
        opts  = self.SEARCH_TYPE[ int(self.core.getSetting('search_type')) ]
        order = self.SEARCH_ORDER[ int(self.core.getSetting('search_order')) ]
        page  = int(page)
        url = '%s/?a=search&search_text=%s&resultsorting=%s&%s&page=%d' \
                % (self.BASE_URL, urllib.quote_plus(qtext), order, opts, page)
        self.wget.request(url)

        found = self.wget.select('div.searchlist')
        if not found:
            self.core.okDialog('StreamCZ', u'Žádné video nenalezeno.')
            raise CancelOperation()

        self.save_search(qtext)

        # add paging links
        for pgLink in self.wget.select('.paging a'):
            m = RE_PAGE.search( pgLink.get('href', '') )
            if m and int(m.group(1)) > page:
                yield PFolder(label=u'<Další stránka>', call='search_result',
                                param={'qtext': qtext, 'page': m.group(1)}
                            )
                break


        for item in found:
            info = {'plot': item.select_first('div.searchlist_content').text}

            m = RE_DATE.search( unicode(item.select_first('div.searchlist_infik')) )
            if m:
                info['date'] = m.group(1)

            iconURL=None
            m = RE_URL.search( item.select_first('a.videolist_one_pic').get('style', '') )
            if m:
                iconURL = m.group(1)

            yield PItem(label=item.select_first('a.searchlist_title').text,
                        call='play',
                        param={'path': item.select_first('a.searchlist_title')['href']},
                        info=info,
                        iconURL=iconURL
                    )



    @plugin_call
    def delete_search(self, qtext):
        """ Delete search from saved search """
        saved_list = self.get_saved_searches()
        if qtext in saved_list:
            saved_list.remove(qtext)
            self.set_saved_searches(saved_list)
        self.core.execute( "Container.Refresh" )


    ### PLAY ###

    @plugin_call
    def play(self, path):
        """ Play video """
        url = self.full_url( path )
        self.core.newProgress('StreamCZ', u'Hledám video stream')
        self.core.updateProgress(30)
        self.debug('play url: '+repr(url))
        self.wget.request( url )
        body = self.wget.select_first('body')
        title = body.select_first('#player_detail h1') \
                or body.select_first('#detail_player h1') \
                or body.select_first('.col_main_b h1') \
                or body.select_first('h1')
        plot = body.select_first('#player_detail_popisek') \
                or body.select_first('.player_detail_text') \
                or body.select_first('#video_popisek')

        info = {}
        if plot and plot.text:
            info['plot'] = plot.text
        item = PItem(
                    label=title.text,
                    info=info,
                )
        player = body.select_first('#player')
        if not player:
            raise "#player not found! - url: "+url
        m = RE_CDN_ID.search( unicode(player) )
        if not m:
            raise "RE_CDN_ID not found!"
        stream_url = CDN_URL % int(m.group(1))
        self.debug('streamURL: '+repr(stream_url) )
        self.core.closeProgress()

        self.core.play(stream_url, item)


    ### Internal methods ###

    def get_saved_searches(self):
        """ Get saved searches list """
        try:
            items = self.core.getSetting("saved_list").split('\n')
            return filter(None, items)
        except:
            return []


    def set_saved_searches(self, saved_list):
        """ Set saved searches list """
        self.core.setSetting('saved_list', '\n'.join(saved_list))


    def save_search(self, qtext):
        """ Save search to saved list """
        saved_list = self.get_saved_searches()
        if qtext not in saved_list:
            saved_list.insert(0, qtext)
            try:
                maxCount = self.MAX_COUNT[int(self.core.getSetting("max_saved_count"))]
            except:
                maxCount = 10
            if len(saved_list) > maxCount:
                saved_list = saved_list[:maxCount]
            self.set_saved_searches(saved_list)


    def full_url(self, path):
        if '://' not in path:
            return self.BASE_URL + path
        return path


    def list_videos(self, path):
        url = self.full_url(path)
        self.wget.request( url )

        # list channels:
        channels = self.wget.select('#sekce_kanalu li a')
        if channels:
            for a in channels:
                yield PFolder(a.text, call='list',
                            param={'path': a['href']}
                        )

        items = self.wget.select('div.videolist_one') \
                    or self.wget.select('div.kanal_1video')
        for div in items:
            plot_div = div.select_first('div.videolist_one_text') \
                        or div.select_first('div.kanal_1video_text')
            title_a = div.select_first('div.videolist_one_content a') \
                        or div.select_first('a.kanal_1video_title')
            img_a = div.select_first('a.videolist_one_pic') \
                        or div.select_first('a.kanal_1video_pic')
            item = PItem(label = title_a.text,
                        call = 'play',
                        param = {'path': title_a['href']},
                        info = {'plot': plot_div.text}
                    )
            m = RE_URL.search( img_a.get('style', '') )
            if m:
                item.iconURL = m.group(1)
            yield item

        nextPageLink = self.next_page_link()
        if nextPageLink:
            yield PFolder(u'<Další strana>', 
                        call='list',
                        param={'path': nextPageLink}
                    )


    def next_page_link(self):
        for a in self.wget.select('div.paging a'):
            if re.match(u'další', a.text, re.U):
                return a['href']
        return None

